package com.sum.tea.viewmodel

import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.sum.common.bean.CommonResult
import com.sum.common.bean.ReadMode
import com.sum.common.bean.ReadParams
import com.sum.common.bean.ReaderExt.*
import com.sum.common.bean.TagInfo
import com.sum.common.bean.WriteParams
import com.sum.common.manager.UHFManager
import com.sum.common.utils.ByteUtil
import com.sum.common.utils.LogU
import com.sum.common.utils.StringUtil

class ReadwriteViewModel : BaseViewModel() {
    private val _readResult = MutableLiveData<CommonResult>()
    val readResult: LiveData<CommonResult> = _readResult
    private var mParams: ReadParams? = null

    private val _writeResult = MutableLiveData<CommonResult>()
    val writeResult: LiveData<CommonResult> = _writeResult
    fun readLabel(params: ReadParams) {
        mParams = params
        try {
            val rdata = ByteArray(params.dataLength * 2)
            val rpaswd = ByteUtil.getPasswordBytes(params.password)
            UHFManager.getInstance().currentManager.clearTagList()
            val result = tryOperation {
                UHFManager.getInstance().currentManager.getTagData(
                    params.region,
                    params.startAddress,
                    params.dataLength,
                    rdata,
                    rpaswd,
                    1000
                )
            }

            if (result == READER_ERR.MT_OK_ERR) {
                val charArray = CharArray(rdata.size * 2)
                StringUtil.Hex2Str(rdata, rdata.size, charArray)
                if(UHFManager.getInstance().isGuoxinDevice){
                    _readResult.value = CommonResult.Success("")
                    setJustReadOnce(true)
                    if(params.region == 2){
                        startReading(ReadMode.GROUP_TID)
                    }else{
                        startReading(ReadMode.NORMAL)
                    }
                }else{
                    _readResult.value = CommonResult.Success(String(charArray))
                }
            } else {
                _readResult.value = CommonResult.Error.getInstance()
            }
        } catch (e: Exception) {
            _readResult.value = CommonResult.Exception(e.message ?: "Unknown error")
        }
    }

    override fun readTag(tagInfoList: List<TagInfo>) {
        if(tagInfoList.isNotEmpty() && mParams != null){
            LogU.d("readTag", "tagInfoList: ${tagInfoList[0]} ,mParams:${mParams!!.region}")
            when(mParams!!.region){
                0 -> _readResult.value = CommonResult.Success(tagInfoList[0].reservedData.toString())
                1 -> _readResult.value = CommonResult.Success(tagInfoList[0].epc.toString())
                2 -> _readResult.value = CommonResult.Success(tagInfoList[0].tid.toString())
                3 -> _readResult.value = CommonResult.Success(tagInfoList[0].userData.toString())
            }
        }
    }

    fun writeLabel(params: WriteParams) {
        try {
            val data = ByteArray(params.writeData.length / 2)
            StringUtil.Str2Hex(params.writeData, params.writeData.length, data)
            val rpaswd = ByteUtil.getPasswordBytes(params.password)

            val result = tryOperation {
                UHFManager.getInstance().currentManager.writeTagData(
                    params,
                    params.region,
                    params.startAddress,
                    params.readData,
                    data,
                    data.size,
                    rpaswd,
                    1000
                )
            }

            _writeResult.value = if (result == READER_ERR.MT_OK_ERR) {
                CommonResult.Success(params.writeData)
            } else {
                CommonResult.Error.getInstance()
            }
        } catch (e: Exception) {
            _writeResult.value = CommonResult.Exception(e.message ?: "Unknown error")
        }
    }

    private fun tryOperation(operation: () -> READER_ERR): READER_ERR {
        var result: READER_ERR
        var tryCount = 1
        do {
            result = operation()
            if (result != READER_ERR.MT_OK_ERR) {
                UHFManager.getInstance().currentManager.getLastDetailError(ErrInfo())
            }
            tryCount--
            if (tryCount < 1) break
        } while (result != READER_ERR.MT_OK_ERR)
        return result
    }
}
